##############################################################################
#
# IperfServer.pm 
# ==============
#
# Author: Steven Liang <stliang@gmail.com>
#
# Purpose:
#   Modeling a iperf running in server mode in Linux
#
# Assumptions:
#   1.) iperf is running on Linux OS
#
# Supported methods:
#   All Linux's methods
#   new($ip, $userName, $passWord ; $port || 23);
#
# Note:
#   Variable after ";" is optional variable and value after "||" is 
#   default value
#
##############################################################################

package IperfServer;
$VERSION = 1.00;

@ISA = qw(Linux); # The @ISA array supports multiple inheritance
		  # For single parent use "use base" key word.

use strict;
use AutoTest::Exceptions;

# Constructor: new
# Purpose:     Instantiate a IperfServer object
# Parameters:
#       1.) ip : IP address of the node
#       2.) userName : User name used for login
#       3.) passWord : Password used for login
#       4.) port : A port to use for telnet, default value is 23
#
# Returns:    An instance of Network::IperfServer class
#
sub new ($$$;$) {
	my $class = shift;
	my $self = { };
	if (defined($_[3])) {
		$self = Node->new($_[0], $_[1], $_[2], $_[3]);
	} else {
		$self = Node->new($_[0], $_[1], $_[2]);
	}
	bless $self, $class;
	return $self;
}

# Method:     start
# Purpose:    Start the iperf in server mode
# Assumption:
#	1.) Linux host's network interface is set with the proper MTU.
#	    One can do this by using the "su" and then "setMTU" methods
#	    
# Parameters:
#       1.) boundIP : The IP address which iperf server bound to
#       2.) resultFileName : The file name which the test result will be stored
#       3.) transport : The default is TCP, pass "-u" to use UDP as the transport
# Returns:    Void
sub start ($$;$) {
        my ($self) = shift;
        my ($boundIP) = shift;
        my ($resultFileName) = shift;
	my ($cmdPrompt) = $self->cmdPrompt();
        my ($transport) = defined($_[0]) ? shift : "";

        $self->{exp}->send("rm -f $resultFileName\r");
	$self->{exp}->expect($self->expectTimeout(), '-re', $cmdPrompt) or 
		AutoTest::Exception::Expect->throw("Failed to remove file specified");

        $self->{exp}->send("touch $resultFileName\r");
	$self->{exp}->expect($self->expectTimeout(), '-re', $cmdPrompt) or 
		AutoTest::Exception::Expect->throw("Tailed to create file specified");

        $self->{exp}->send("iperf -s $transport -B $boundIP > $resultFileName\r");
	$self->{exp}->expect($self->expectTimeout(), '-re', ".*");

        print "\n========================================================";
        print "\n Started Iperf Server Successfully";
        print "\n iperf -s $transport -B $boundIP > $resultFileName";
        print "\n========================================================\n";

}

# Method:     getResult
# Purpose:    Parse the result file for performance test result
# Parameters:
#       1.) fileName : The name of the file used to store iperf test result
# Returns:
#       The line that contains the test result
sub getResult ($) {
        my ($self) = shift;
        my ($fileName) = shift;
	my ($result) = "";
        my $cmdPrompt = $self->cmdPrompt();

	# Terminate iperf server by sending "control c"
        $self->{exp}->send("\x03");
        $self->{exp}->expect($self->expectTimeout(),
                [
                qr"Interrupt again",
                sub {
			sleep(60);
                        $self->{exp}->send("\x03");
			$self->{exp}->expect($self->expectTimeout(), '-re', "*");
                    }
                ],
                '-re', $cmdPrompt
        );

        $self->{exp}->send("\r");
        $self->{exp}->expect($self->expectTimeout(), '-re', $cmdPrompt) or
                AutoTest::Exception::Expect->throw("Failed to stop iperf server");

        $self->{exp}->send("cat $fileName\r");
        $self->{exp}->expect($self->expectTimeout(), '-re', $cmdPrompt) or
                AutoTest::Exception::Expect->throw("Unable to get iperf server test result");

        my $results = $self->{exp}->before();
        my @lines = split ( /\n/, $results);
        my $line = "";
        foreach $line (@lines) {
		#print "\nDEBUG: processing line: $line";
		if ($line =~ /\%\)/) {
			$result = $line;
                        last;
		}
        }

        return $result;
}
